from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.orm import Session
from datetime import datetime, timedelta
from typing import Dict, Optional
import logging

from backend.config.database import get_db
from backend.utils.weather_api import WeatherAPIService
from backend.utils.entsoe_api import ENTSOEAPIService
from pydantic import BaseModel

class StandardResponse(BaseModel):
    success: bool
    message: str
    data: Optional[dict] = None

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/yesterday", tags=["前一天数据"])

@router.get("/weather", response_model=StandardResponse)
async def get_yesterday_weather(db: Session = Depends(get_db)):
    """
    获取前一天的气象数据
    
    Returns:
        StandardResponse: 包含气象数据的响应
    """
    try:
        # 获取前一天的日期
        yesterday = (datetime.now() - timedelta(days=1)).date()
        yesterday_str = yesterday.strftime('%Y-%m-%d')
        
        logger.info(f"获取前一天气象数据: {yesterday_str}")
        
        # 创建气象API服务
        weather_api = WeatherAPIService()
        
        # 获取气象数据
        weather_df = weather_api.get_weather_data(yesterday_str, yesterday_str)
        
        if weather_df is None or weather_df.empty:
            # 尝试直接使用OpenMeteo API作为备选
            logger.info("尝试使用OpenMeteo API作为备选")
            try:
                weather_df = weather_api._get_weather_from_openmeteo(yesterday_str, yesterday_str)
            except Exception as e:
                logger.error(f"OpenMeteo API也失败: {e}")
                raise HTTPException(status_code=500, detail="无法获取气象数据")
        
        if weather_df is None or weather_df.empty:
            raise HTTPException(status_code=500, detail="无法获取气象数据")
        
        # 转换为字典格式
        weather_data = weather_df.iloc[0].to_dict()
        
        # 确定数据源
        data_source = "visualcrossing" if yesterday < datetime.now().date() else "openmeteo"
        weather_data['data_source'] = data_source
        weather_data['dt'] = yesterday_str
        
        return StandardResponse(
            success=True,
            message=f"成功获取 {yesterday_str} 的气象数据",
            data=weather_data
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取前一天气象数据失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取气象数据失败: {str(e)}")

@router.get("/load", response_model=StandardResponse)
async def get_yesterday_load(db: Session = Depends(get_db)):
    """
    获取前一天的负荷数据
    
    Returns:
        StandardResponse: 包含负荷数据的响应
    """
    try:
        # 获取前一天的日期
        yesterday = (datetime.now() - timedelta(days=1)).date()
        yesterday_str = yesterday.strftime('%Y-%m-%d')
        
        logger.info(f"获取前一天负荷数据: {yesterday_str}")
        
        # 创建ENTSO-E API服务
        entsoe_api = ENTSOEAPIService()
        
        # 验证API token
        if not entsoe_api.validate_token():
            raise HTTPException(status_code=500, detail="ENTSO-E API token验证失败")
        
        # 获取负荷数据
        load_df = entsoe_api.get_load_data(yesterday_str, yesterday_str)
        
        if load_df is None or load_df.empty:
            raise HTTPException(status_code=500, detail="无法获取负荷数据")
        
        # 转换为字典格式
        load_data = {
            'dt': yesterday_str,
            'data_points': len(load_df),
            'load_values': load_df.to_dict('records')
        }
        
        return StandardResponse(
            success=True,
            message=f"成功获取 {yesterday_str} 的负荷数据",
            data=load_data
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取前一天负荷数据失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取负荷数据失败: {str(e)}")

@router.get("/all", response_model=StandardResponse)
async def get_yesterday_all_data(db: Session = Depends(get_db)):
    """
    获取前一天的气象和负荷数据
    
    Returns:
        StandardResponse: 包含气象和负荷数据的响应
    """
    try:
        # 获取前一天的日期
        yesterday = (datetime.now() - timedelta(days=1)).date()
        yesterday_str = yesterday.strftime('%Y-%m-%d')
        
        logger.info(f"获取前一天所有数据: {yesterday_str}")
        
        # 创建API服务
        weather_api = WeatherAPIService()
        entsoe_api = ENTSOEAPIService()
        
        # 验证ENTSO-E API token
        if not entsoe_api.validate_token():
            raise HTTPException(status_code=500, detail="ENTSO-E API token验证失败")
        
        # 获取气象数据
        weather_df = weather_api.get_weather_data(yesterday_str, yesterday_str)
        if weather_df is None or weather_df.empty:
            # 尝试直接使用OpenMeteo API作为备选
            try:
                weather_df = weather_api._get_weather_from_openmeteo(yesterday_str, yesterday_str)
            except Exception as e:
                logger.error(f"OpenMeteo API也失败: {e}")
                weather_df = None
        
        # 获取负荷数据
        load_df = entsoe_api.get_load_data(yesterday_str, yesterday_str)
        
        # 准备响应数据
        response_data = {
            'date': yesterday_str,
            'weather': None,
            'load': None,
            'success': True
        }
        
        # 处理气象数据
        if weather_df is not None and not weather_df.empty:
            weather_data = weather_df.iloc[0].to_dict()
            data_source = "visualcrossing" if yesterday < datetime.now().date() else "openmeteo"
            weather_data['data_source'] = data_source
            weather_data['dt'] = yesterday_str
            response_data['weather'] = weather_data
        else:
            response_data['success'] = False
            response_data['weather_error'] = "无法获取气象数据"
        
        # 处理负荷数据
        if load_df is not None and not load_df.empty:
            load_data = {
                'dt': yesterday_str,
                'data_points': len(load_df),
                'load_values': load_df.to_dict('records')
            }
            response_data['load'] = load_data
        else:
            response_data['success'] = False
            response_data['load_error'] = "无法获取负荷数据"
        
        return StandardResponse(
            success=response_data['success'],
            message=f"获取 {yesterday_str} 的数据完成",
            data=response_data
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取前一天所有数据失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取数据失败: {str(e)}")

@router.post("/save", response_model=StandardResponse)
async def save_yesterday_data(db: Session = Depends(get_db)):
    """
    获取并保存前一天的数据到数据库
    
    Returns:
        StandardResponse: 保存结果
    """
    try:
        from backend.service.data_update_service import DataUpdateService
        
        # 创建数据更新服务
        update_service = DataUpdateService()
        
        # 执行更新
        result = update_service.update_yesterday_data()
        
        if result['success']:
            return StandardResponse(
                success=True,
                message=result['message'],
                data=result['details']
            )
        else:
            raise HTTPException(status_code=500, detail=result['error'])
            
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"保存前一天数据失败: {e}")
        raise HTTPException(status_code=500, detail=f"保存数据失败: {str(e)}") 